/**
 *
 */
package bg.btanev.eightyfour.client.utils;

import java.util.Vector;

import com.google.gwt.user.client.ui.ListBox;

/**
 *
 * @author B.Tanev
 *
 */
public final class SelectionUtils {

	/**
	 * Hides Default Constructor.
	 */
	private SelectionUtils() {
	}

	public static final SelectionStrategy EQUALS_TEXT_SELECTION_STRATEGY = EqualsTextSelectionStrategy.getInstance();
	public static final SelectionStrategy EQUALS_VALUE_SELECTION_STRATEGY = EqualsValueSelectionStrategy.getInstance();
	public static final SelectionStrategy ENDS_WITH_TEXT_SELECTION_STRATEGY = EndsWithTextSelectionStrategy
			.getInstance();

	/**
	 *
	 * @param listBox
	 * @param str
	 * @return
	 */
	private static boolean ifEmptyStringSelectNone(ListBox listBox, String str) {
		if (str == null || str.length() == 0) {
			listBox.setSelectedIndex(-1);
			return false;
		}
		return true;
	}

	public static void selectValueFromList(ListBox listBox, String value) {
		selectValueFromList(listBox, value, EQUALS_TEXT_SELECTION_STRATEGY);
	}

	public static void selectValueFromList(ListBox listBox, String value, SelectionStrategy strategy) {
		if (ifEmptyStringSelectNone(listBox, value)) {
			boolean selected = false;
			for (int index = 0; index < listBox.getItemCount(); index++) {
				if (strategy.confirm(listBox.getValue(index), listBox.getItemText(index), value)) {
					listBox.setSelectedIndex(index);
					selected = true;
					break;
				}
			}
			if (!selected) {
				listBox.setSelectedIndex(-1);
			}
		}
	}

	/**
	 *
	 * @param listBox
	 * @return the selected items value as string or <b>null</b> is nothing is selected
	 */
	public static String getSelectedValue(ListBox listBox) {
		int selectedIndex = listBox.getSelectedIndex();
		if (selectedIndex == -1) {
			return null;
		}
		return listBox.getValue(selectedIndex);
	}

	@SuppressWarnings("unchecked")
	public static String[] getMultipleSelectedValues(ListBox listBox) {
		String[] resultArr = null;
		Vector result = new Vector();
		int firstSelected = listBox.getSelectedIndex();
		if (firstSelected != -1) {
			for (int i = firstSelected; i < listBox.getItemCount(); i++) {
				if (listBox.isItemSelected(i)) {
					result.add(listBox.getValue(i));
				}
			}
			resultArr = (String[]) result.toArray(new String[result.size()]);
		}
		return resultArr;
	}

	@SuppressWarnings("unchecked")
	public static String[] getMultipleSelectedTexts(ListBox listBox) { // NO_UCD
		String[] resultArr = null;
		Vector result = new Vector();
		int firstSelected = listBox.getSelectedIndex();
		if (firstSelected != -1) {
			for (int i = firstSelected; i < listBox.getItemCount(); i++) {
				if (listBox.isItemSelected(i)) {
					result.add(listBox.getItemText(i));
				}
			}
			resultArr = (String[]) result.toArray(new String[result.size()]);
		}
		return resultArr;
	}

	/**
	 *
	 * @param listBox
	 * @return the selected string from the list box or <b>null</b> is nothing is selected
	 */
	public static String getSelectedText(ListBox listBox) {
		int selectedIndex = listBox.getSelectedIndex();
		if (selectedIndex == -1) {
			return null;
		}
		return listBox.getItemText(selectedIndex);
	}

	public static interface SelectionStrategy {

		public abstract boolean confirm(String itemValue, String itemText, String userValue);
	}

	private static class EqualsTextSelectionStrategy implements SelectionUtils.SelectionStrategy {
		private static final EqualsTextSelectionStrategy INSTANCE = new EqualsTextSelectionStrategy();

		public static SelectionStrategy getInstance() {
			return INSTANCE;
		}

		private EqualsTextSelectionStrategy() {

		}

		public boolean confirm(String itemValue, String itemText, String userValue) {
			if (itemText != null) {
				return itemText.equals(userValue);
			}
			return false;
		}

	}

	private static class EqualsValueSelectionStrategy implements SelectionUtils.SelectionStrategy {
		private static final EqualsValueSelectionStrategy INSTANCE = new EqualsValueSelectionStrategy();

		public static SelectionStrategy getInstance() {
			return INSTANCE;
		}

		private EqualsValueSelectionStrategy() {

		}

		public boolean confirm(String itemValue, String itemText, String userValue) {
			if (itemValue != null) {
				return itemValue.equals(userValue);
			}
			return false;
		}

	}

	private static class EndsWithTextSelectionStrategy implements SelectionUtils.SelectionStrategy {
		private static final EndsWithTextSelectionStrategy INSTANCE = new EndsWithTextSelectionStrategy();

		public static SelectionStrategy getInstance() {
			return INSTANCE;
		}

		private EndsWithTextSelectionStrategy() {

		}

		public boolean confirm(String itemValue, String itemText, String userValue) {
			if (itemText != null) {
				return itemText.endsWith(userValue);
			}
			return false;
		}
	}

	/**
	 *
	 * @param listBox
	 * @param listener
	 * @throws NullPointerException
	 *             if given list box is null.
	 */
	public static void selectFirstItemIfAvailable(ListBox listBox, SelectFirstElementListener listener)
			throws NullPointerException {
		if (listBox == null) {
			throw new NullPointerException("listBox cannot be null.");
		}
		if (listBox.getItemCount() > 0) {
			listBox.setSelectedIndex(0);
			if (listener != null) {
				listener.onSelectFirstElement(listBox);
			}
		}
	}

	/**
	 *
	 * @param listBox
	 * @throws NullPointerException
	 */
	public static void selectFirstItemIfAvailable(ListBox listBox) throws NullPointerException {
		selectFirstItemIfAvailable(listBox, null);
	}

	public static interface SelectFirstElementListener {
		public abstract void onSelectFirstElement(ListBox listBox);
	}
}
